package common.common.Util;


import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import net.minidev.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token
 * WebToken制作器
 * 可重复登录
 * 1.0.0
 */
public class JWTutil {

    private final static Logger logger = LoggerFactory.getLogger(JWTutil.class);

    private static final byte[] Secret_key = "askdjhaoisuhklanwjldgirsvrhqzoku".getBytes();

    public static String craateToken(String groud, String visibleId, String MiID) throws JOSEException {

        //先处理如果有值为空的情况
        if (visibleId.isEmpty()||MiID.isEmpty()) {
            throw new NullPointerException("其中有值为空");
        }

        //制作载荷
        Map<String, Object> map = new HashMap<>();

        map.put("visibleId", visibleId);

        map.put("tokenId", MiID);

        map.put("groud",groud);

        map.put("NowTime", new Date().getTime());

        map.put("EndTime", new Date().getTime() + 200 * 1000 * 60);


        //制作头
        JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

        //载荷
        Payload payload = new Payload(JSONObject.toJSONString(map));

        //头和载荷连接
        JWSObject jwsObject = new JWSObject(jwsHeader, payload);

        //建立秘钥
        JWSSigner jwsSigner = null;
        try {
            jwsSigner = new MACSigner(Secret_key);
        } catch (KeyLengthException e) {

            logger.error("这里发生了一个键长度的异常");
        }

        //制作签名
        try {
            jwsObject.sign(jwsSigner);
        } catch (JOSEException e) {
            logger.error("签名发生了异常");
        }

        return jwsObject.serialize();
    }


    //解析token
    public static Boolean Analysis(String token) {
        JWSObject jwsObject = null;
        Payload payload = null;
        JWSVerifier jwsVerifier = null;
        boolean falg = false;

        //解析token
        try {
            jwsObject = JWSObject.parse(token);
            //获取载荷
            payload = jwsObject.getPayload();
            jwsVerifier = new MACVerifier(Secret_key);
            //效验token是否为有效token
            falg = jwsObject.verify(jwsVerifier);
        } catch (ParseException e) {
            logger.error("Token parsing failed, please check the server" + e.getMessage());
            return false;
        } catch (JOSEException e) {
            logger.error("服务器建立解锁秘钥出错查看日志" + e.getMessage());
            return false;
        }

        if (falg) {
            //从载荷里面获取时间
            Map<String, Object> jsonObject = payload.toJSONObject();
            //效验在载荷里面是否有时间
            if (jsonObject.containsKey("EndTime")) {
                Long endTime = Long.valueOf(jsonObject.get("EndTime").toString());
                Long nowTime = new Date().getTime();
                //验证是否过期了token的时间
                if (nowTime < endTime) {
                    return true;//有效token
                } else {
                    return false;//无效token
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    //获取指定的token载荷内容
    //考虑到一些问题以后优化暂时不做

    /**
     * @param token
     * @param content
     * @return
     */
    public static String GetPayload(String token, String content) {
//        final Base64.Decoder decoder = Base64.getDecoder();
        JWSObject jwsObject = null;
        Payload payload = null;
        try {
            jwsObject = JWSObject.parse(token);
        } catch (ParseException e) {
            logger.error("Token parsing failed, please check the server");
            return "Token parsing failed";
        }
        payload = jwsObject.getPayload();
        Map<String, Object> jsonObject = payload.toJSONObject();

        return (String) jsonObject.get(content);
    }

}
